"""
仓位计算器

负责根据策略参数计算买入仓位大小
"""

import logging

logger = logging.getLogger(__name__)


class PositionCalculator:
    """
    仓位计算器
    
    根据以下因素计算仓位：
    - 基准仓位
    - 价格位置系数（低位/高位）
    - 市值系数（大盘/中盘/小盘）
    - 量能强度系数（强烈/温和/正常）
    """
    
    def __init__(self, config: dict):
        """
        初始化仓位计算器
        
        Args:
            config: 仓位配置字典，包含：
                - base_position: 基准仓位（如0.20表示20%）
                - price_position_coef: 价格位置系数
                - market_cap_coef: 市值系数
                - volume_strength_coef: 量能强度系数
                - batch_ratios: 分批建仓比例
        """
        self.config = config
        self.base_position = config.get('base_position', 0.20)
        self.price_coef = config.get('price_position_coef', {'low': 1.0, 'high': 0.6})
        self.market_cap_coef = config.get('market_cap_coef', {'large': 1.0, 'mid': 0.8, 'small': 0.6})
        self.volume_coef = config.get('volume_strength_coef', {'strong': 1.0, 'moderate': 0.8, 'normal': 0.6})
        self.batch_ratios = config.get('batch_ratios', {'first': 0.70, 'second': 0.30})
        
    def calculate_target_position(self, 
                                  strategy_type: str,
                                  stock_type: str,
                                  volume_strength: str) -> float:
        """
        计算目标仓位
        
        Args:
            strategy_type: 策略类型 ('low' or 'high')
            stock_type: 股票类型 ('large', 'mid', 'small')
            volume_strength: 量能强度 ('strong', 'moderate', 'normal')
            
        Returns:
            float: 目标仓位比例（0-1之间）
        """
        try:
            # 价格位置系数
            price_coef = self.price_coef.get(strategy_type, 1.0)
            
            # 市值系数
            market_coef = self.market_cap_coef.get(stock_type, 0.8)
            
            # 量能强度系数
            volume_coef = self.volume_coef.get(volume_strength, 0.8)
            
            # 计算最终仓位
            target_position = self.base_position * price_coef * market_coef * volume_coef
            
            logger.debug(f"仓位计算: {self.base_position:.2%} × {price_coef} × {market_coef} × {volume_coef} = {target_position:.2%}")
            
            return target_position
            
        except Exception as e:
            logger.error(f"仓位计算失败: {str(e)}")
            return 0.10  # 默认返回10%
    
    def calculate_first_batch_position(self, target_position: float) -> float:
        """
        计算首次建仓仓位
        
        - 如果启用加仓功能：返回目标仓位 × first比例（如70%）
        - 如果不启用加仓：返回100%目标仓位（一次性买入）
        
        Args:
            target_position: 目标仓位
            
        Returns:
            float: 首次建仓仓位
        """
        # 检查是否启用加仓功能
        add_conditions = self.config.get('add_position_conditions', {})
        enabled = add_conditions.get('enabled', False)
        
        if not enabled:
            # 不启用加仓：一次性买入100%目标仓位
            logger.debug(f"加仓功能未启用，首次建仓使用100%目标仓位: {target_position:.2%}")
            return target_position
        
        # 启用加仓：按first比例买入
        first_ratio = self.batch_ratios.get('first', 0.70)
        first_position = target_position * first_ratio
        logger.debug(f"加仓功能已启用，首次建仓使用{first_ratio:.0%}目标仓位: {first_position:.2%}")
        return first_position
    
    def calculate_second_batch_position(self, target_position: float) -> float:
        """
        计算第二次加仓仓位
        
        Args:
            target_position: 目标仓位
            
        Returns:
            float: 第二次加仓仓位
        """
        second_ratio = self.batch_ratios.get('second', 0.30)
        return target_position * second_ratio
    
    def calculate_sell_ratio(self, condition_type: str, trigger_count: int) -> float:
        """
        计算卖出比例（完全从配置文件读取，无硬编码）
        
        Args:
            condition_type: 卖出条件类型 ('A', 'B1', 'B2', 'C')
            trigger_count: 触发次数（仅用于条件A）
            
        Returns:
            float: 卖出比例（0-1之间）
        """
        # 卖出比例映射表
        sell_ratio_map = {
            'B1': 1.0,  # 条件B1：天量出货，立即清仓
            'B2': 1.0,  # 条件B2：放量滞涨，全部清仓
            'C': 1.0    # 条件C：跌破5日线，清仓剩余
        }
        
        # 条件A：分批减仓（从配置动态读取所有批次）
        if condition_type == 'A':
            sell_batch_ratios = self.config.get('sell_batch_ratios', {'first': 0.30, 'second': 0.40})
            
            # 动态读取所有减仓批次配置
            batch_keys = ['first', 'second', 'third', 'fourth', 'fifth']  # 支持最多5批
            sell_ratios_list = []
            for key in batch_keys:
                if key in sell_batch_ratios:
                    ratio = sell_batch_ratios[key]
                    if ratio > 0:  # 只添加有效的比例
                        sell_ratios_list.append(ratio)
                else:
                    break  # 遇到不存在的key就停止
            
            # 根据触发次数返回对应批次的比例
            if trigger_count > 0 and trigger_count <= len(sell_ratios_list):
                ratio = sell_ratios_list[trigger_count - 1]
                logger.debug(f"条件A第{trigger_count}次触发，减仓{ratio:.0%}")
                return ratio
            else:
                # 超过配置的批次数，全部清仓
                logger.debug(f"条件A第{trigger_count}次触发，超过配置批次({len(sell_ratios_list)}批)，全部清仓")
                return 1.0
        
        # 其他条件使用映射表
        if condition_type in sell_ratio_map:
            return sell_ratio_map[condition_type]
        
        # 未知条件类型
        logger.warning(f"未知的卖出条件类型: {condition_type}")
        return 1.0
    
    def get_position_info_string(self, 
                                 stock: str,
                                 target_position: float,
                                 first_batch: float,
                                 strategy_type: str,
                                 stock_type: str,
                                 volume_strength: str) -> str:
        """
        生成仓位信息字符串（用于日志）
        
        Returns:
            str: 格式化的仓位信息
        """
        strategy_name = "低位标准策略" if strategy_type == 'low' else "高位强势策略"
        stock_type_name = {'large': '大盘股', 'mid': '中盘股', 'small': '小盘股'}.get(stock_type, stock_type)
        volume_name = {'strong': '强烈放量', 'moderate': '温和放量', 'normal': '正常量能'}.get(volume_strength, volume_strength)
        
        return (f"{stock} [{strategy_name}|{stock_type_name}|{volume_name}] "
                f"目标仓位: {target_position*100:.1f}%, 首次建仓: {first_batch*100:.1f}%")

